package com.ruoyi.client.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.ruoyi.client.pojo.form.UserLoginForm;
import com.ruoyi.client.pojo.form.UserRegisterForm;
import com.ruoyi.client.pojo.form.UserUpdatePwdForm;
import com.ruoyi.client.pojo.vo.UserLoginVo;
import com.ruoyi.client.pojo.vo.UserRegisterVo;
import com.ruoyi.client.pojo.vo.UserVo;
import com.ruoyi.client.service.ClientUserService;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;

@Api(tags = "4-用户接口")
@RestController
@RequestMapping("/user")
public class ClientUserController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(ClientUserController.class);

    @Resource
    private ClientUserService clientUserService;
    @Resource
    private RedisCache redisCache;

    /**
     * 用户登录
     */
    @Anonymous
    @ApiOperation(value = "用户登录", notes = "返回用户id、name、avatar、phone、token")
    @ApiImplicitParam(name = "form", value = "用户登录参数", dataType = "UserLoginForm", required = true)
    @PostMapping("/login")
    public R<UserLoginVo> login(@RequestBody UserLoginForm form) {
        UserLoginVo userLoginVo = clientUserService.login(form);
        // 增加用户ID非空校验，提前拦截异常
        Long userId = userLoginVo.getId();
        if (userId == null) {
            throw new ServiceException("用户ID获取失败，请检查登录逻辑");
        }
        // 初始化Sa-Token会话
        StpUtil.login(userId);
        String token = StpUtil.getTokenValue();
        // 构建Redis缓存键，并缓存用户信息
        String userKey = CacheConstants.LOGIN_TOKEN_KEY + token;
        redisCache.setCacheObject(userKey, userLoginVo);
        // 设置Token到返回结果
        userLoginVo.setToken(token);
        logger.info("用户{}登录成功，Token：{}", userId, token);
        return R.ok(userLoginVo);
    }

    /**
     * 用户注册
     */
    @Anonymous
    @ApiOperation(value = "用户注册")
    @ApiImplicitParam(name = "form", value = "用户注册参数", dataType = "UserRegisterForm", required = true)
    @PostMapping("/register")
    public R<UserRegisterVo> register(@RequestBody @Valid UserRegisterForm form){
        UserRegisterVo userRegisterVo = clientUserService.register(form);
        return R.ok(userRegisterVo);
    }

    /**
     * 查询我的详情
     */
    @SaCheckLogin
    @ApiOperation(value = "查询我的详情", notes = "查询当前登录用户的详情信息")
    @GetMapping("/detail")
    public R<UserVo> detail() {
        UserVo userVo = clientUserService.getMyDetail();
        return R.ok(userVo);
    }

    /**
     * 修改密码
     */
    @SaCheckLogin
    @ApiOperation(value = "修改密码", notes = "需验证原密码，修改成功后需重新登录")
    @ApiImplicitParam(name = "form", value = "修改密码参数", dataType = "UserUpdatePwdForm", required = true)
    @PostMapping("/updatePwd")
    public R<?> updatePassword(@RequestBody @Valid UserUpdatePwdForm form) {
        clientUserService.updatePassword(form);
        // 密码修改后强制登出当前会话
        StpUtil.logout();
        return R.ok("密码修改成功，请重新登录");
    }
}